package stanaGUI.KMeans;

import java.util.ArrayList;
import java.util.List;

public class Cluster {
	private List<Item> items;
	private double medianVal1;
	private double medianVal2;
	private double higherVal1 =0;
	private double lowerVal1 = Double.MAX_VALUE;
	private double higherVal2 =0;
	private double lowerVal2 = Double.MAX_VALUE;
	
	private double sum1 = 0; // FOR MEAN
	private double sum2 = 0; // FOR MEAN
	
	//Constructor of empty cluster with a specified median (for  K-means)
	public Cluster (double medianVal1, double medianVal2) {
		
		this.items = new ArrayList<Item>();
		this.medianVal1 = medianVal1;
		this.medianVal2 = medianVal2;
	}
	
	public Cluster(List<Item> newItems){
		this.items = new ArrayList<Item>(newItems);
		calculateMedian();
	}
	
	public Cluster(List<Item> newItems, List<Item> newItems2){
		this.items = new ArrayList<Item>(newItems);
		items.addAll(newItems2);
		calculateMedian();
	}
	
	public Cluster(Item item){
		this.items = new ArrayList<Item>();
		this.items.add(item);
		// calculate median
		this.medianVal1 = item.getValue1();
		this.medianVal2 = item.getValue2();
	}
	
	
	// To perform merges
	public void addItemsFromCluster(Cluster cluster2){
		getItems().addAll(cluster2.getItems());
	}
	
	public void addItem(Item item) {
		getItems().add(item);
		sum1 += item.getValue1();
	}
	
	public void addItems(List<Item> newItems) {
		for(Item item : newItems){
			this.getItems().add(item);
			sum1 += item.getValue1();
		}
	}

	public List<Item> getItems() {
		return items;
	}
	
	public int size(){
		return getItems().size();
	}

	public double getMedianVal1() {
		return medianVal1;
	}
	public double getMedianVal2() {
		return medianVal2;
	}
	
	public String toString(){
		String retour = "(";
		for(Item item : getItems()){
			retour = retour + item.getValue1() + ",";
		}
		retour = retour + ")      <" + medianVal1 + ", min=" + getLowerVal1() + " max=" + getHigherVal1() + ">";
		return retour;
	}
	public double[] center(){
		int size = getItems().size();
		double center1 = 0;
		double center2 = 0;
		for(Item item : getItems()){
			center1 = center1+item.getValue1()/(double)size;
			center2 = center2+item.getValue2()/(double)size;
		}
		double[] center = {center1,center2};
		return center;
	}
	
	
	private void calculateMedian() {
		if(getItems().isEmpty()){
			return;
		}
		
		if(getItems().size() ==1){
			medianVal1 = getItems().get(0).getValue1();
			medianVal2 = getItems().get(0).getValue2();
			return;
		}
		// VERSION USING THE AVERAGE
		medianVal1 = sum1 /((double)items.size());
		medianVal2 =  sum2 /((double)items.size());
	}
		

	public void recomputeClusterMedian() {
		calculateMedian();
	}
	
	public void computeHigherAndLower(){
		for(Item item : getItems()){
			if(item.getValue1() > higherVal1){
				higherVal1 = item.getValue1();
			}
			if(item.getValue1() < lowerVal1){
				lowerVal1 = item.getValue1();
			}
			if(item.getValue2() > higherVal2){
				higherVal2 = item.getValue2();
			}
			if(item.getValue2() < lowerVal2){
				lowerVal2 = item.getValue2();
			}

		}
	}

	public boolean containsItem(Item item2) {
		for(Item item : getItems()){
			if(item == item2) {
				return true;
			}
		}
		return false;
	}

	public double getHigherVal1() {
		return higherVal1;
	}
	public double getLowerVal1() {
		return lowerVal1;
	}

	public double getHigherVal2() {
		return higherVal2;
	}
	public double getLowerVal2() {
		return lowerVal2;
	}


}
